package gui;

import enums.TextBundleEnum;
import enums.URLEnum;
import gui.filefilter.XMLFileFilter;
import gui.filefilter.XMLFileView;
import gui.other.Dimensions;
import gui.panel.AboutPanel;
import gui.panel_new.*;
import internationalization.Internationalizer;
import j_util.Utiles;
import misc.BundlesProvider;
import org.jvnet.substance.SubstanceLookAndFeel;
import org.jvnet.substance.skin.SubstanceMistAquaLookAndFeel;
import org.jvnet.substance.skin.SubstanceModerateLookAndFeel;
import org.jvnet.substance.skin.SubstanceSaharaLookAndFeel;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.ArrayList;
/*

    This file is part of Logica-Logike.

    Logica-Logike is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation version 3 of the License.

    Logica-Logike is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with Logica-Logike.  If not, see <http://www.gnu.org/licenses/>.

 */
/**
 * Clase que contiene el ejecutable principal para la ensenanza de logica;
 *
 * @author Jose Martin Rozanec;
 */
public class MainFrame {

    public static void main(String[] args) {
        /*Preloading javaHelp
        //JavaHelp preloading to avoid unnecesary waiting
        java.util.List<File> fileList = new ArrayList<File>();
        Utiles.getAllFilesListedInSubdirectories("LogicaHelpNoTeoria", fileList);
        File[] files = fileList.toArray(new File[fileList.size()]);
        URL[] urls = new URL[files.length];
        for (int j = 0; j < files.length; j++) {
            try {
                System.out.println("" + files[j].getAbsolutePath());
                urls[j] = files[j].toURI().toURL();
            } catch (MalformedURLException e) {
                e.printStackTrace();
            }
        }
        //This does not work. The piece of code is left, in order to track (if necessary) where the retrieval of
        //javaHelp sources is done
        ClassLoader loader = new URLClassLoader(urls);
        */
        Internationalizer.setSpanish();
        final ResourceBundle textBundle = BundlesProvider.getBundle(URLEnum.TEXT_BUNDLE);
        JFrame.setDefaultLookAndFeelDecorated(true);
        try {            
            UIManager.setLookAndFeel("org.jvnet.substance.skin.SubstanceOfficeSilver2007LookAndFeel");
//            UIManager.setLookAndFeel(new SubstanceOfficeSilver2007LookAndFeel());
        } catch (Exception e) {
            System.out.println("Substance OfficeSilver2007 failed to initialize");
        }
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                final JButton saveAsButton;
                final JButton openButton;
                final JFileChooser fileChooser = new JFileChooser();
                fileChooser.setFileFilter(new XMLFileFilter());
                fileChooser.setFileView(new XMLFileView());


                final JTabbedPane tabbedPane = new JTabbedPane();

                saveAsButton = new JButton(Utiles.createImageIcon(URLEnum.getReference(URLEnum.SAVE_AS)));
                openButton = new JButton(Utiles.createImageIcon(URLEnum.getReference(URLEnum.OPEN)));
                openButton.setEnabled(false);

                final JFrame mainFrame = new JFrame();
                JToolBar toolBar = new JToolBar();
                toolBar.setFloatable(false);
                toolBar.setVisible(true);

                JButton aboutButton = new JButton(Utiles.createImageIcon(URLEnum.getReference(URLEnum.ABOUT)));
                aboutButton.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        JDialog dialog = new JDialog();
                        Dimension frameDimension = new Dimension(650, 690);
                        JTabbedPane tabbedPane = new JTabbedPane();
                        tabbedPane.add(new AboutPanel(), textBundle.getString(TextBundleEnum.LOGICA.toString()));
                        JEditorPane aboutTheAuthorsPanel = null;
//                        try {
//                            aboutTheAuthorsPanel = new JEditorPane("jar:file:"+new File("").getAbsolutePath()+"/aboutAuthors.jar!/aboutAuthors.html");
//
////                            "jar:file:"+new File("").getAbsolutePath()+"/aboutAuthors.jar!/aboutAuthors.html"
////                            "file:aboutAuthors.html"
//
////                            java.net.URL authorsURL = MainFrame.class.getResource(
////                                "aboutAuthors.html");
////                        aboutTheAuthorsPanel.setPage(authorsURL);
//                            aboutTheAuthorsPanel.setEditable(false);
//                        } catch (IOException e1) {
//                            e1.printStackTrace();
//                        }
//
//                        tabbedPane.add(aboutTheAuthorsPanel, textBundle.getString(TextBundleEnum.THE_AUTHORS.toString()));
                        dialog.setContentPane(tabbedPane);
                        dialog.setTitle(textBundle.getString(TextBundleEnum.ABOUT.toString()));
                        dialog.setIconImage(Utiles.createImageIcon(URLEnum.getReference(URLEnum.INFORMATION)).getImage());
                        dialog.setPreferredSize(frameDimension);
                        dialog.setSize(frameDimension);
                        dialog.setMinimumSize(frameDimension);
                        dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
                        dialog.setResizable(false);
                        Utiles.centerDialog(dialog);
                        dialog.setModal(true);
                        dialog.setVisible(true);
                    }
                });

                OposicionPanel oposicionPanel = new OposicionPanel(saveAsButton, openButton, fileChooser);
                SilogismoPanel silogismoPanel = new SilogismoPanel(saveAsButton, openButton, fileChooser);
                PolisilogismoPanel polisilogismoPanel = new PolisilogismoPanel(saveAsButton, openButton, fileChooser);
                TruthTablePanel truthTablePanel = new TruthTablePanel(saveAsButton, openButton, fileChooser);
                VennPanel vennPanel = new VennPanel(saveAsButton, openButton, fileChooser);
                URL hsURL=null;
//                try {
//                    hsURL = new URL("jar:file:"+new File("").getAbsolutePath()+"/helpJars/logicaHelp.jar!/HelpSet.hs");
//                    System.out.println("OK!!!"+hsURL.toString());
//                } catch (MalformedURLException e) {
//                    e.printStackTrace();
//                }
                HelpPanel teoriaPanel = new HelpPanel("LogicaHelp/HelpSet.hs", saveAsButton, openButton, fileChooser);
//                String url = hsURL.getPath().replace("!/","!");
//                url = url.replace("\\","/");
//                System.out.println(""+url);
                HelpPanel helpPanel = new HelpPanel("LogicaHelpNoTeoria/HelpSet.hs", saveAsButton, openButton, fileChooser);
//                HelpPanel helpPanel = new HelpPanel(hsURL.toString().replace("logicaHelp","logicaHelpNoTeoria"), saveAsButton, openButton, fileChooser);
                oposicionPanel.refreshOpenSaveButtons();

                tabbedPane.addTab(textBundle.getString(TextBundleEnum.OPOSICION.toString()), null, oposicionPanel);
                tabbedPane.addTab(textBundle.getString(TextBundleEnum.SILOGISMO.toString()), null, silogismoPanel);
                tabbedPane.addTab(textBundle.getString(TextBundleEnum.POLISILOGISMO.toString()), null, polisilogismoPanel);
                tabbedPane.addTab(textBundle.getString(TextBundleEnum.TABLA_VERDAD.toString()), null, truthTablePanel);
                tabbedPane.addTab(textBundle.getString(TextBundleEnum.DIAGRAMAS_VENN.toString()), null, vennPanel);
                tabbedPane.addTab(textBundle.getString(TextBundleEnum.TEORIA.toString()), null, teoriaPanel);
                tabbedPane.addTab(textBundle.getString(TextBundleEnum.AYUDA_LOGICA.toString()) + " " +
                        textBundle.getString(TextBundleEnum.VERSION_NUMERO.toString()), null, helpPanel);
                tabbedPane.addChangeListener(new ChangeListener() {
                    public void stateChanged(ChangeEvent e) {
                        if (((JTabbedPane) e.getSource()).getSelectedComponent().getClass().toString().equals("class gui.panel_new.VennPanel")) {
                            ((VennPanel) ((JTabbedPane) e.getSource()).getSelectedComponent()).refreshOpenSaveButtons();
                        } else {
                            if (((JTabbedPane) e.getSource()).getSelectedComponent().getClass().toString().equals("class gui.panel_new.TruthTablePanel")) {
                                ((TruthTablePanel) ((JTabbedPane) e.getSource()).getSelectedComponent()).refreshOpenSaveButtons();
                            } else {
                                if (((JTabbedPane) e.getSource()).getSelectedComponent().getClass().toString().equals("class gui.panel_new.PolisilogismoPanel")) {
                                    ((PolisilogismoPanel) ((JTabbedPane) e.getSource()).getSelectedComponent()).refreshOpenSaveButtons();
                                } else {
                                    if (((JTabbedPane) e.getSource()).getSelectedComponent().getClass().toString().equals("class gui.panel_new.SilogismoPanel")) {
                                        ((SilogismoPanel) ((JTabbedPane) e.getSource()).getSelectedComponent()).refreshOpenSaveButtons();
                                    } else {
                                        if (((JTabbedPane) e.getSource()).getSelectedComponent().getClass().toString().equals("class gui.panel_new.OposicionPanel")) {
                                            ((OposicionPanel) ((JTabbedPane) e.getSource()).getSelectedComponent()).refreshOpenSaveButtons();
                                        } else {
                                            if (((JTabbedPane) e.getSource()).getSelectedComponent().getClass().toString().equals("class gui.panel_new.HelpPanel")) {
                                                ((HelpPanel) ((JTabbedPane) e.getSource()).getSelectedComponent()).refreshOpenSaveButtons();
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                });

                toolBar.add(openButton);
                toolBar.add(saveAsButton);
                toolBar.add(aboutButton);
                toolBar.add(new JLabel(Utiles.createImageIcon(URLEnum.getReference(URLEnum.SEPARATOR))));
                toolBar.add(new JLabel(Utiles.createImageIcon(URLEnum.getReference(URLEnum.SEPARATOR_110))));
                toolBar.add(new JLabel(Utiles.createImageIcon(URLEnum.getReference(URLEnum.LOOK_FEEL))));

                JRadioButton office2007RadioButton = createLFRadioButton(mainFrame, "org.jvnet.substance.skin.SubstanceOfficeSilver2007LookAndFeel", 1);//new SubstanceOfficeSilver2007LookAndFeel()
                office2007RadioButton.setSelected(true);

                JRadioButton aquaRadioButton = createLFRadioButton(mainFrame, "org.jvnet.substance.skin.SubstanceMistAquaLookAndFeel", 2);

                JRadioButton saharaRadioButton = createLFRadioButton(mainFrame, "org.jvnet.substance.skin.SubstanceSaharaLookAndFeel", 3);

                JRadioButton moderateRadioButton = createLFRadioButton(mainFrame, "org.jvnet.substance.skin.SubstanceModerateLookAndFeel", 4);

                ButtonGroup radioButtonGroup = new ButtonGroup();
                radioButtonGroup.add(office2007RadioButton);
                radioButtonGroup.add(aquaRadioButton);
                radioButtonGroup.add(saharaRadioButton);
                radioButtonGroup.add(moderateRadioButton);

                toolBar.add(office2007RadioButton);
                toolBar.add(aquaRadioButton);
                toolBar.add(saharaRadioButton);
                toolBar.add(moderateRadioButton);

                mainFrame.add(toolBar, BorderLayout.NORTH);
                mainFrame.add(tabbedPane);

                mainFrame.setSize(700, Dimensions.FRAME_HEIGHT);
                mainFrame.setTitle(textBundle.getString(TextBundleEnum.LOGICA.toString()) + " " +
                        textBundle.getString(TextBundleEnum.VERSION_NUMERO.toString()));
                mainFrame.setIconImage(Utiles.createImageIcon(URLEnum.getReference(URLEnum.LOGICA_ICON)).getImage());
                mainFrame.setResizable(false);

                switch (readLookAndFeelConfig()) {
                    case 2:
                        setLookAndFeel(aquaRadioButton, new SubstanceMistAquaLookAndFeel());
                        break;
                    case 3:
                        setLookAndFeel(saharaRadioButton, new SubstanceSaharaLookAndFeel());
                        break;
                    case 4:
                        setLookAndFeel(moderateRadioButton, new SubstanceModerateLookAndFeel());
                        break;
                }

                mainFrame.setVisible(true);
                mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            }
        });
    }

    /**
     * Escribe un archivo de configuracion en el que especifica el look and feel usado;
     *
     * @param lookAndFeel;
     */
    public static void writeLookAndFeelConfig(int lookAndFeel) {
        try {
            RandomAccessFile configFile = new RandomAccessFile(URLEnum.getReference(URLEnum.CONFIG_FILE), "rw");
            configFile.writeInt(lookAndFeel);
            configFile.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * Lee el archivo de configuracion y establece el look & feel utilizado por ultima vez;
     *
     * @return int - look and feel;
     */
    public static int readLookAndFeelConfig() {
        try {
            RandomAccessFile configFile = new RandomAccessFile(URLEnum.getReference(URLEnum.CONFIG_FILE), "rw");
            return configFile.readInt();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            writeLookAndFeelConfig(1);
        }
        return -1;
    }

    /**
     * Crea un radioButton cuya seleccion cambia el look and feel al especificado;
     *
     * @param frame;
     * @param lookAndFeel;
     * @param lookAndFeelID;
     * @return JRadioButton;
     */
    private static JRadioButton createLFRadioButton(final JFrame frame, final SubstanceLookAndFeel lookAndFeel, final int lookAndFeelID) {
        JRadioButton radioButton = new JRadioButton();
        radioButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                try {
                    UIManager.setLookAndFeel(lookAndFeel);
                    frame.repaint();
                    writeLookAndFeelConfig(lookAndFeelID);
                } catch (UnsupportedLookAndFeelException e1) {
                    System.out.println("Failed " + lookAndFeel.getDescription());
                }
            }
        });
        return radioButton;
    }

    /**
     * Crea un radioButton cuya seleccion cambia el look and feel al especificado;
     *
     * @param frame;
     * @param lookAndFeel;
     * @param lookAndFeelID;
     * @return JRadioButton;
     */
    private static JRadioButton createLFRadioButton(final JFrame frame, final String lookAndFeel, final int lookAndFeelID) {
        JRadioButton radioButton = new JRadioButton();
        radioButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                try {
                    UIManager.setLookAndFeel(lookAndFeel);
                    frame.repaint();
                    writeLookAndFeelConfig(lookAndFeelID);
                } catch (UnsupportedLookAndFeelException e1) {
                    System.out.println("Failed " + lookAndFeel);
                } catch (ClassNotFoundException e1) {
                    e1.printStackTrace();
                } catch (IllegalAccessException e1) {
                    e1.printStackTrace();
                } catch (InstantiationException e1) {
                    e1.printStackTrace();
                }
            }
        });
        return radioButton;
    }

    /**
     * Permite setear el look and feel;
     *
     * @param radioButton;
     * @param lookAndFeel;
     */
    private static void setLookAndFeel(JRadioButton radioButton, SubstanceLookAndFeel lookAndFeel) {
        radioButton.setSelected(true);
        try {
            UIManager.setLookAndFeel(lookAndFeel);
        } catch (UnsupportedLookAndFeelException e1) {
            System.out.println("Failed " + lookAndFeel.getDescription());
        }
    }

    /**
     * Permite setear el look and feel;
     *
     * @param radioButton;
     * @param lookAndFeel;
     */
    private static void setLookAndFeel(JRadioButton radioButton, String lookAndFeel) {
        radioButton.setSelected(true);
        try {
            UIManager.setLookAndFeel(lookAndFeel);
        } catch (UnsupportedLookAndFeelException e1) {
            System.out.println("Failed " + lookAndFeel);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
    }
}